package com.googlecode.lucene.appengine.objectify.util;

import com.googlecode.objectify.Key;
import com.googlecode.objectify.Objectify;
import com.googlecode.objectify.ObjectifyFactory;

/**
 * Utility methods to work with {@link ObjectifyUtil}.
 * @author Fabio Grucci (github: <i>UltimaPhoenix</i>, bitbucket: <i>Dark_Phoenix</i>, googlecode: <i>fabio.grucci</i>)
 *
 */
public enum ObjectifyUtil {
	;

	public static <T> Key<T> newKey(final Class<T> clazz, final long id) {
		return new Key<T>(clazz, id);
	}
	
	public static <T> Key<T> newKey(final Class<T> clazz, final String name) {
		return new Key<T>(clazz, name);
	}
	
	public static <P, C> Key<C> newChildKey(final Class<P> parentClass, final long parentId, final Class<C> childClass, final long childId) {
		return new Key<C>(newKey(parentClass, parentId), childClass, childId);
	}
	
	public static <P, C> Key<C> newChildKey(final Class<P> parentClass, final long parentId, final Class<C> childClass, final String childName) {
		return new Key<C>(newKey(parentClass, parentId), childClass, childName);
	}
	
	public static <P, C> Key<C> newChildKey(final Class<P> parentClass, final String parentName, final Class<C> childClass, final long childId) {
		return new Key<C>(newKey(parentClass, parentName), childClass, childId);
	}
	
	public static <P, C> Key<C> newChildKey(final Class<P> parentClass, final String parentName, final Class<C> childClass, final String childName) {
		return new Key<C>(newKey(parentClass, parentName), childClass, childName);
	}
	
	public static <T> T getOrCreate(ObjectifyFactory objectifyFactory, Key<T> key, ObjectifyBuilder<T> builder) {
		Objectify objectify = objectifyFactory.begin();
		T t = objectify.find(key);
		if(t == null) {
			objectify = objectifyFactory.beginTransaction();
			try {
				t = objectify.find(key);
				if(t == null) {
					t = builder.newIstance(key);
					key = objectify.put(t);
				}
				commit(objectify);
			} finally {
				closeQuietly(objectify);
			}
		}
		return t;
	}
	
	public static void commit(Objectify objectify) {
		objectify.getTxn().commit();
	}
	

	public static void closeQuietly(Objectify objectify) {
		if (objectify.getTxn().isActive())
			objectify.getTxn().rollback();
	}
	
}
